
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpRequest, HttpEvent, HttpEventType, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, last, map, tap } from 'rxjs/operators';
import SparkMD5 from 'spark-md5';

export interface Config {
    kdjson: {
        api: string;
        flag: string;
        detail?: string;
        time?: string;
        len?: string;
        code?: string;
        timeSpent?: string;
        msg?: string;
        items?;
    }
}
export interface loginparams {
    id_token: string
}

@Injectable()
export class AppService {
    isLoggedIn: boolean = true; //登陆状态
    redirectUrl: string = '/login';
    userInfo = { chinesename: 'kk.' }; //用户类型
    menuObject = [
        { 'name': 'index', 'links': '/home/index', 'selected': false },
        { 'name': 'bpmn-js', 'links': '/home/bpmn', 'selected': false },
        { 'name': 'fullcalendar', 'links': '/fullcalendar', 'selected': false },
        { 'name': 'ckeditor', 'links': '/ckeditor', 'selected': false },
        { 'name': 'Editor.md', 'links': '/editor', 'selected': false },
        { 'name': 'js-xlsx', 'links': '/home/xlsx', 'selected': false },
    ];
    Accept: string;
    httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json;charset=UTF-8',
            "Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMDAwMDEiLCJhdXRoIjoiUk9MRV9VU0VSIiwiSlNFU1NJT05JRCI6Ijk3NTljZmUyLWIzNTEtNDcwNy1hMTU2LTZhYjM4NjM4YWQ5MSJ9.RshjxtdHXQFMYNj8yleY_CesfusG0bmhBpLHyKI5CxaVz0GkGNMrOC4SADStT50cZHfwicA7VVlOPFyRHJhsaA"
        })
    }

    constructor(
        private http: HttpClient,
    ) { }

    public setUserInfo(info: object) {
        this.userInfo = { ...this.userInfo, ...info };
    }

    public getUserName() {
        return this.userInfo.chinesename;
    }

    public getMenuObject() {
        return this.menuObject;
    }

    public getNewApi(apiName, params) {
        return this.http.post(apiName, params, this.httpOptions);
    }

    public getLoginName() {
        return this.http.post('/login_name', {});
    }

    public logout() {
        return this.http.post('/logout', {}).subscribe(() => {
            this.httpOptions.headers.set('Authorization', '')
        });;
    }

    public upload(file: File, ajaxdata) {
        if (!file) { return; }

        const getMd5A = (file) => {
            const blobSlice = File.prototype.slice;
            const chunkSize = 5 * 1024 * 1024;                         // Read in chunks of 2MB
            const chunks = Math.ceil(file.size / chunkSize);
            let currentChunk = 0;
            const spark = new SparkMD5.ArrayBuffer();
            const fileReader = new FileReader();
            function loadNext() {
                const start = currentChunk * chunkSize;
                const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
                fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
            }
            fileReader.onload = (e) => {
                spark.append(e.target.result);                   // Append array buffer
                currentChunk += 1;
                if (currentChunk < chunks) {
                    loadNext();
                } else {
                    const md5New = spark.end();
                    getChunk(file, md5New);
                }
            }
            loadNext();
        }

        const getChunk = (file, md5) => {
            const bytesPerPiece = 5 * 1024 * 1024; // 每个文件切片大小定为5MB .
            const filesize = file.size;
            const filename = file.name;
            const totalPieces: any = Math.ceil(filesize / bytesPerPiece);
            let start = 0;
            let end;
            let chunk: any = 0;

            while (start < filesize) {
                end = start + bytesPerPiece;
                if (end > filesize) {
                    end = filesize;
                }
                const fileChunk = file.slice(start, end);// 切割文件    
                const formData = new FormData();
                formData.append("chunk", chunk);
                formData.append("chunks", totalPieces);
                formData.append("md5", md5);
                Object.keys(ajaxdata).forEach(key => {
                    if (ajaxdata[key]) formData.append(key, ajaxdata[key]);
                });
                formData.append("docname", filename);
                formData.append("file", fileChunk, filename);
                reqwestFile(formData);
                chunk += 1;
                start = end;
            }
        }

        const reqwestFile = (formData) => {
            const tokenid = sessionStorage.getItem('tokenid');
            const req = new HttpRequest('POST', '/doc', formData, { responseType: 'text' });
            return this.http.request(req).pipe(catchError(this.handleError()));
        }

        getMd5A(file);
    }

    private handleError() {
        return (error: HttpErrorResponse) => {
            // TODO: send the error to remote logging infrastructure
            // console.error(error); // log to console instead
            const message = (error.error instanceof Error) ? error.error.message : `server returned code ${error.status} with body "${error.error}"`;
            return of(message);
        };
    }
}